package com.mazaiting.manager.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mazaiting.common.core.domain.result.ResultCode;
import com.mazaiting.common.core.ex.exceptions.BaseException;
import com.mazaiting.common.core.ex.exceptions.BusinessException;
import com.mazaiting.common.core.ex.exceptions.EmptyObjectException;
import com.mazaiting.manager.convert.IDictTypeConverter;
import com.mazaiting.manager.domain.entity.SysDictItem;
import com.mazaiting.manager.domain.entity.SysDictType;
import com.mazaiting.manager.domain.form.DictTypeForm;
import com.mazaiting.manager.domain.query.DictTypePageQuery;
import com.mazaiting.manager.domain.vo.dict.DictTypePageVO;
import com.mazaiting.manager.mapper.ISysDictTypeMapper;
import com.mazaiting.manager.service.ISysDictItemService;
import com.mazaiting.manager.service.ISysDictTypeService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * 字典类型服务
 *
 * @author mazaiting
 * @since 2022-03-25
 */
@Service
@RequiredArgsConstructor
public class SysDictTypeServiceImpl extends ServiceImpl<ISysDictTypeMapper, SysDictType> implements ISysDictTypeService {

    private final IDictTypeConverter dictTypeConverter;

    private final ISysDictItemService sysDictItemService;

    @Override
    public Page<DictTypePageVO> listPages(DictTypePageQuery queryParams) {
        // 查询参数
        int pageNum = queryParams.getPageNum();
        int pageSize = queryParams.getPageSize();
        String keywords = queryParams.getKeywords();

        // 查询数据
        Page<SysDictType> dictTypePage = lambdaQuery().like(StringUtils.hasLength(keywords), SysDictType::getName, keywords)
                .or()
                .like(StringUtils.hasLength(keywords), SysDictType::getCode, keywords)
                .select(SysDictType::getId, SysDictType::getName, SysDictType::getCode, SysDictType::getStatus)
                .page(new Page<>(pageNum, pageSize));

        // 实体转换
        return dictTypeConverter.entity2Page(dictTypePage);
    }

    @Override
    public boolean save(DictTypeForm dictTypeForm) throws BusinessException {
        Optional<SysDictType> sysDictTypeOpt = lambdaQuery().eq(SysDictType::getCode, dictTypeForm.getCode()).oneOpt();
        if (sysDictTypeOpt.isPresent()) {
            throw new BusinessException(ResultCode.DICT_TYPE_EXIST);
        }
        // 实体对象转换 form->entity
        SysDictType entity = dictTypeConverter.form2Entity(dictTypeForm);
        entity.setId(null);
        // 持久化
        return save(entity);
    }

    @Override
    public boolean update(DictTypeForm dictTypeForm) throws BaseException {
        // 根据 ID 查询是否不存在
        SysDictType sysDictType = getById(dictTypeForm.getId());
        if (Objects.isNull(sysDictType)) {
            throw new EmptyObjectException(ResultCode.DICT_TYPE_EMPTY);
        }
        // 根据 code 判断是否存在
        Optional<SysDictType> sysDictTypeOpt = lambdaQuery()
                .eq(SysDictType::getCode, dictTypeForm.getCode())
                .ne(SysDictType::getId, dictTypeForm.getId())
                .oneOpt();
        if (sysDictTypeOpt.isPresent()) {
            throw new BusinessException(ResultCode.DICT_TYPE_EXIST);
        }
        // 实体对象转换 form->entity
        SysDictType entity = dictTypeConverter.form2Entity(dictTypeForm);
        // 持久化
        boolean result = updateById(entity);
        if (result) {
            // 字典类型code变化，同步修改字典项的类型code
            String oldCode = sysDictType.getCode();
            String newCode = dictTypeForm.getCode();
            if (!Objects.equals(oldCode, newCode)) {
                // 更新码值
                sysDictItemService.update(new LambdaUpdateWrapper<SysDictItem>()
                        .eq(SysDictItem::getTypeCode, oldCode)
                        .set(SysDictItem::getTypeCode, newCode)
                );
            }
        }
        return result;
    }

    @Override
    public boolean delete(String idsStr) {
        // 分割字符串
        List<Long> ids = Arrays.stream(idsStr.split(","))
                .map(Long::parseLong)
                .toList();

        // 删除字典项
        List<String> dictTypeCodes = lambdaQuery().in(SysDictType::getId, ids).select(SysDictType::getCode).list()
                .stream().map(SysDictType::getCode).toList();
        if (CollectionUtil.isNotEmpty(dictTypeCodes)) {
            sysDictItemService.remove(new LambdaQueryWrapper<SysDictItem>().in(SysDictItem::getTypeCode, dictTypeCodes));
        }
        // 删除字典类型
        return this.removeByIds(ids);
    }

    @Override
    public DictTypeForm getDictTypeFormData(Long id) throws EmptyObjectException {
        // 获取entity
        Optional<SysDictType> sysDictTypeOpt = lambdaQuery().eq(SysDictType::getId, id)
                .select(
                        SysDictType::getId,
                        SysDictType::getName,
                        SysDictType::getCode,
                        SysDictType::getStatus,
                        SysDictType::getRemark
                ).oneOpt();
        if (sysDictTypeOpt.isEmpty()) {
            throw new EmptyObjectException(ResultCode.DICT_TYPE_EMPTY);
        }
        SysDictType entity = sysDictTypeOpt.get();

        // 实体转换
        return dictTypeConverter.entity2Form(entity);
    }
}
